package cn.mesmile.juc.forkjoin;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.TimeInterval;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;

/**
 * @author zb
 * @date 2021/8/18 14:25
 * @Description
 */
public class ForkJoinDemo {

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        TimeInterval timer = DateUtil.timer();
        MyTask myTask = new MyTask(1, 100);
        // 创建分支合并池对象
        ForkJoinPool forkJoinPool = new ForkJoinPool();
        // 提交任务
        ForkJoinTask<Integer> forkJoinTask = forkJoinPool.submit(myTask);
        // 获取结果
        Integer integer = forkJoinTask.get();
        Integer rawResult = forkJoinTask.getRawResult();

        System.out.println("timer.interval() = " + timer.interval());
        System.out.println("integer = " + integer);
        System.out.println("rawResult = " + rawResult);
        // 关闭forkjoin 池
        forkJoinPool.shutdown();

    }

}

class MyTask extends RecursiveTask<Integer> {

    // 拆分差值不能超过 10，计算 10 以内运算
    private static final Integer VALUE = 30;
    // 拆分开始值
    private int begin;
    // 拆分结束值
    private int end;
    // 返回结果
    private int result;

    public MyTask(int begin, int end){
        this.begin = begin;
        this.end = end;
    }

    @Override
    protected Integer compute() {
        // 拆分和合并
        int number = end - begin;
        // 若小于 10 则不拆分
        if (number <= VALUE){
            for (int i = begin; i <= end ; i++) {
                result = result + i;
            }
        } else {
          // 大于10 则拆分
            int middle = (begin + end) /2;
            // 拆分左边
            MyTask myTask01 = new MyTask(begin, middle);
            // 拆分右边
            MyTask myTask02 = new MyTask(middle+1, end);
            // 拆分
            myTask01.fork();
            myTask02.fork();
            // 合并结果
            result = myTask01.join() + myTask02.join();
        }
        return result;
    }

}
